//:C07:BasicSequenceOperations.cpp
// The operations available for all the
// basic sequence Containers.
#include <deque>
#include <iostream>
#include <list>
#include <vector>
using namespace std;

template<typename Container>
void print(Container& c, char* title = "")
{
    cout << title << ':' << endl;
    if(c.empty())
    {
        cout << "(empty)" << endl;
        return;
    }
    typename Container::iterator it;
    for (it = c.begin(); it != c.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
    cout << "size() " << c.size()
         << " max_size() " << c.max_size()
         << " front() " << c.front()
         << " back() " << c.back()
         << endl;
}

template<typename ContainerOfInt> 
void basicOps(char* s)
{
    cout << "--------" << s << "  --------" << endl;
    typedef ContainerOfInt Ci;
    Ci c;
    print(c, "c after default constructor");
    Ci c2(10, 1);    // 10 elements, values all 1;
    print(c2, "c2 after constructor(10, 1)");
    int ia[] = {1, 3, 5, 7, 9};
    const int IASZ = sizeof(ia) / sizeof(*ia);
    // Initialize with begin & end iterators:
    Ci c3(ia, ia + IASZ);
    print(c3, "c3 after constructor(iter, iter)");
    Ci c4(c2);   // Copy-constructor
    print(c4, "c4 after copy-constructor(c2)");
    c = c2;   // Assignment operator
    print(c, "c after operator=c2");
    c.assign(10, 2);    // 10 elements, values all 2
    print(c, "c after assign(10, 2)");
    // Assign with begin & end iterators:
    c.assign(ia, ia + IASZ);
    print(c, "c after assign(iter, iter)");
    cout << "c using reverse iterators:" << endl;
    typename Ci::reverse_iterator rit = c.rbegin();
    while(rit != c.rend())
    {
        cout << *rit++ << " ";
    }
    cout << endl;
    c.resize(4);
    print(c, "c after resize(4)");
    c.push_back(47);
    print(c, "c after push_back(47)");
    c.pop_back();
    print(c, "c after pop_back()");
    typename Ci::iterator it = c.begin();
    ++it;
    ++it;
    c.insert(it, 74);
    print(c, "c after insert(it, 74)");
    it = c.begin();
    ++it;
    c.insert(it, 3, 96);
    print(c, "c after insert(it, 3, 96)");
    it = c.begin();
    ++it;
    c.insert(it, c3.begin(), c3.end());
    print(c, "c after insert(it, c3.begin(), c3.end())");
    it = c.begin();
    ++it;
    c.erase(it);
    print(c, "c after erase(it)");
    typename Ci::iterator it2 = it = c.begin();
    ++it;
    ++it2;
    ++it2;
    ++it2;
    ++it2;
    ++it2;
    c.erase(it, it2);
    print(c, "c after erase(it ,it2)");
    c.swap(c2);
    print(c, "c after swap(c2)");
    c.clear();
    print(c, "c after clear()");
}

int main(void)
{
    basicOps<vector<int>>("vector");
    basicOps<deque<int>>("deque");
    basicOps<list<int>>("list");
}